home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Garbo
/
Garbo.cdr
/
mac
/
hypercrd
/
hc1_2_x
/
fretext1.sit
/
Free Text Source Code
/
openCloseFiles 0.7.c
< prev
next >
Wrap
Text File
|
1990-01-27
|
9KB
|
397 lines
/* openCloseFiles ([params]) XFCN source code
* copyright 1990 - Mark Zimmermann
*
* - specially modified (for potential CD-ROM applications) -- so that it can:
* 1) open any file types, not just TEXT and CTLZ, for database & indices
* 2) ask for location of the index file(s) if not found in same folder
* as the main file, with the suffix '.k' or '.p'
*
* Call this XFCN as 'openCloseFiles([optional list of numbers here])'.
*
* If the XFCN is called with no arguments, it puts up the standard files
* dialog box and gives back in return the file refNums for the main
* (document/database) file, *.k, and *.p files, on one line, in
* that order, separated by spaces. The XFCN also returns, on a second
* line, the file name of the file that has been opened.
*
* If the XFCN is passed any numerical parameters, it attempts to
* close them (assuming they are file refNums) and doesn't try to
* open anything....
*
* If an error while opening a file seems to occur, the XFCN attempts
* to close all files that have already been opened, and returns with
* an error msg instead of the three file refNums. No error checking
* is done on closing files, since there's not much that one could
* do about such an error in any case....
*
*/
#include <MacTypes.h>
#include <FileMgr.h>
#include <StdFilePkg.h>
#include <HyperXCmd.h>
#include <SetUpA4.h>
#define NULL 0
pascal void main (XCmdBlockPtr paramPtr);
int zGetFile (Str255 *fileNamePtr, int *volRefNumPtr, long fileType);
void give_msg (char *msg);
void returnErrorMsg (XCmdBlockPtr paramPtr, char *msg);
long atol (char *s);
void ltoaR (char *ansp, long n, int maxDigits);
int strlen (char *s);
char *strcpy (char *s1, char *s2);
pascal void main (paramPtr)
XCmdBlockPtr paramPtr;
{
Str255 fileName;
int refNum, volRefNum, textFileRefNum, keyFileRefNum, ptrFileRefNum,
i, errNum;
Handle answer;
WindowRecord w_record;
WindowPtr info_window;
Rect b_rect;
RememberA0 ();
SetUpA4();
if (paramPtr->paramCount != 0)
{
for (i = 0; i < paramPtr->paramCount; ++i)
{
refNum = atol (*(paramPtr->params[i]));
FSClose (refNum);
}
RestoreA4();
return;
}
/* set up a window to give user feedback during file opening... */
b_rect.top = 30;
b_rect.left = 12;
b_rect.bottom = 332;
b_rect.right = 500;
info_window = NewWindow (&w_record, &b_rect, "\p", (Boolean)1,
dBoxProc, (WindowPtr)-1, (Boolean)0, (long)0);
ShowWindow (info_window);
SetPort (info_window);
TextFont (0);
give_msg ("\pPlease choose a database (indexed file) to open...");
/* note that file type 'TEXT' is now ignored here! */
if (! zGetFile (&fileName, &volRefNum, 'TEXT'))
{
DisposeWindow (info_window);
RestoreA4();
return;
}
errNum = FSOpen (&fileName, volRefNum, &textFileRefNum);
if (errNum != noErr && errNum != opWrErr)
{
returnErrorMsg (paramPtr,
"{Sorry, error in opening database file!}");
DisposeWindow (info_window);
RestoreA4();
return;
}
*(fileName + *fileName + 1) = '.';
*(fileName + *fileName + 2) = 'k';
*fileName += 2;
errNum = FSOpen (&fileName, volRefNum, &keyFileRefNum);
if (errNum != noErr && errNum != opWrErr)
{
SysBeep (10);
give_msg ("\p");
give_msg ("\pSorry, can't find the index key ('.k') file for this database!");
give_msg ("\pPlease locate it, or cancel...");
/* note that file type 'CTLZ' is now ignored here! */
if (! zGetFile (&fileName, &volRefNum, 'CTLZ'))
{
FSClose (textFileRefNum);
DisposeWindow (info_window);
RestoreA4();
return;
}
else
{
errNum = FSOpen (&fileName, volRefNum, &keyFileRefNum);
if (errNum != noErr && errNum != opWrErr)
{
FSClose (textFileRefNum);
returnErrorMsg (paramPtr,
"{Sorry, error in opening index key ('.k') file!}");
DisposeWindow (info_window);
RestoreA4();
return;
}
}
}
*(fileName + *fileName) = 'p';
errNum = FSOpen (&fileName, volRefNum, &ptrFileRefNum);
if (errNum != noErr && errNum != opWrErr)
{
SysBeep (10);
give_msg ("\p");
give_msg ("\pSorry, can't find the index ptr ('.p') file for this database!");
give_msg ("\pPlease locate it, or cancel...");
/* note that file type 'CTLZ' is now ignored here! */
if (! zGetFile (&fileName, &volRefNum, 'CTLZ'))
{
FSClose (textFileRefNum);
FSClose (keyFileRefNum);
DisposeWindow (info_window);
RestoreA4();
return;
}
else
{
errNum = FSOpen (&fileName, volRefNum, &ptrFileRefNum);
if (errNum != noErr && errNum != opWrErr)
{
FSClose (textFileRefNum);
FSClose (keyFileRefNum);
returnErrorMsg (paramPtr,
"{Sorry, error in opening index ptr ('.p') file!}");
DisposeWindow (info_window);
RestoreA4();
return;
}
}
}
if ((answer = NewHandle (64)) == NULL)
{
FSClose (textFileRefNum);
FSClose (keyFileRefNum);
FSClose (ptrFileRefNum);
returnErrorMsg (paramPtr,
"{Sorry, bad out of memory error in XFCN openFiles call!}");
DisposeWindow (info_window);
RestoreA4();
return;
}
ltoaR (*answer, textFileRefNum, 6);
ltoaR (*answer + 6, keyFileRefNum, 6);
ltoaR (*answer + 12, ptrFileRefNum, 6);
*(*answer + 18) = '\r';
for (i = 1; i <= *fileName - 2; ++i)
*(*answer + 18 + i) = fileName[i];
*(*answer + 18 + i) = '\0';
paramPtr->returnValue = answer;
DisposeWindow (info_window);
RestoreA4();
return;
}
/* this routine does the standard files dialog to get the name of the main file
* of the database; other file names are gotten from that by putting
* a '.k' or a '.p' at the end. This routine returns 1 if all is well,
* or 0 if the user cancels out...
*
* special mod to open any file, not just type text...keep the myFileTypes
* parameter in there, even though it's not used any more....who knows when
* it might come in handy?!
*/
int zGetFile (fileNamePtr, volRefNumPtr, fileType)
Str255 *fileNamePtr;
int *volRefNumPtr;
long fileType;
{
SFTypeList myFileTypes;
Point SFGwhere;
SFReply myReply;
register int i;
SFGwhere.v = 90;
SFGwhere.h = 82;
myFileTypes[0] = fileType;
/* main change is to put in the '-1' here to signify that file
* type doesn't matter to SFGetFile
*/
SFGetFile (SFGwhere, "\p", 0L, -1, myFileTypes, 0L, &myReply);
if (myReply.good)
{
for (i = *myReply.fName; i >= 0; --i)
(*fileNamePtr)[i] = myReply.fName[i];
*volRefNumPtr = myReply.vRefNum;
return (1);
}
else
return (0);
}
/* tiny routine to put a message into my message window.... takes in a
* PASCAL type string and displays it nicely....
*/
void give_msg (msg)
char *msg;
{
Rect b_rect;
RgnHandle theRgn;
b_rect.top = b_rect.left = 0;
b_rect.bottom = 302;
b_rect.right = 488;
theRgn = NewRgn ();
ScrollRect (&b_rect, 0, -15, theRgn);
DisposeRgn (theRgn);
MoveTo (4, 295);
DrawString (msg);
return;
}
/* function to set the return value of the XFCN to a chosen error msg;
* if there isn't enough free memory to give us a Handle to the msg,
* beep a bit and then return!
*/
void returnErrorMsg (paramPtr, msg)
XCmdBlockPtr paramPtr;
char *msg;
{
Handle answer;
int msgLength;
SysBeep (10);
msgLength = strlen (msg);
if ((answer = NewHandle (1 + msgLength)) == NULL)
{
SysBeep (10);
SysBeep (10);
return;
}
strcpy (*answer, msg);
paramPtr->returnValue = answer;
return;
}
/* function to convert alphanumeric string to a long int, from K&R...
*/
long atol (s)
register char *s;
{
int signflag = 0;
register long r = 0;
while (*s == ' ')
s++;
if (*s == '-')
{
signflag = 1;
s++;
}
else if (*s == '+')
s++;
while (*s >= '0' && *s <= '9')
r = r * 10 + (*s++ - '0');
return (signflag ? -r : r);
}
/* function to convert a number into a string of width maxDigits and
* store it right-justified, blank-filled on left; based on K&R p. 60
* example of itoa().
*
* Error handling: put a '>' or '<' in leading place to warn of an
* overflow (no room for digits on a positive or negative number,
* respectively), and put a '^' in leading place to warn if no room
* for '-' sign on negative number...
*/
void ltoaR (ansp, n, maxDigits)
register char *ansp;
register long n;
int maxDigits;
{
register int i;
long sign;
i = maxDigits - 1;
if ((sign = n) < 0)
n = -n;
do
{
ansp[i--] = n % 10 + '0';
}
while ((n /= 10) > 0 && i >= 0);
if (i < 0 && n > 0) /* ran out of room with digits still to go */
{
if (sign > 0)
ansp[0] = '>'; /* positive overflow signal */
else
ansp[0] = '<'; /* negative overflow signal */
}
else
{
if (sign < 0)
if (i >= 0)
ansp[i--] = '-';
else
ansp[0] = '^'; /* no room for '-' sign signal */
for ( ; i >= 0; --i)
ansp[i] = ' ';
}
return;
}
/* function to determine the length of a string ... standard thing,
* adapted from K&R p.98 ....
*/
int strlen (s)
register char *s;
{
char *s0 = s;
while (*s++)
;
return (s - s0 - 1);
}
/* function to copy a string from one place to another, in a rather
* obvious fashion ... adapted from K&R p.101 ....
*/
char *strcpy (s1, s2)
register char *s1, *s2;
{
char *s = s1;
while (*s1++ = *s2++)
;
return (s);
}